<template>
  <div class="assign-tree-dimension" ref="treeRoot">
    <span class="operation-hint" v-if="treeData.length > 0">{{ $t("module.dataPermission.warning.hintInfo") }}</span>
    <el-tree
      class="treeStyle"
      :data="treeData"
      ref="objectTree"
      :props="treeProps"
      node-key="dimensionDataId"
      :show-checkbox="true"
      icon-class="ivu-icon-ios-arrow-forward"
      @check-change="onCheckChange"
      @node-contextmenu="onRightClick"
      @node-click="onNodeClick"
      :check-strictly="true"
      :empty-text="hintText"
    >
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <Tooltip :content="$t('common.frozen')" :disabled="data.enabled != 0 || data.isAllot != 1" placement="top">
          <span :class="data.enabled == 0 && data.isAllot == 1 ? 'invalidStyle' : ''">
            {{ node.label }}
            <Icon type="md-done-all" v-if="data.recursive" style="margin-left: 5px;" />
          </span>
        </Tooltip>
      </span>
    </el-tree>
    <div class="tree-menu" :style="styleObject">
      <div class="menu-item" @click="checkCurrentNode()">
        {{ $t("module.dataPermission.warning.checkCurrentNode") }}
      </div>
      <div class="menu-item" @click="checkChildrenNode()">
        {{ $t("module.dataPermission.warning.checkChildrenNode") }}
      </div>
    </div>
  </div>
</template>
<script>
import locales from "./locales.js";
import dataPermissionAPI from "@/api/dataPermissionAPI.js";
import { CONTROL_LEVEL_ORG, CONTROL_LEVEL_ROLE, CONTROL_LEVEL_USER } from "./const.js";

export default {
  name: "AssignTreeDimension",
  mixins: [locales],
  props: {
    tenantCode: { type: String, required: true },
    dimensionId: String,
    assignmentId: String,
    dimensionCode: String,
    controlLevel: {
      type: Number,
      default() {
        return 0;
      }
    }
  },
  data() {
    return {
      treeData: [],
      treeProps: {
        children: "children",
        label: "dimensionDataName"
      },
      searchForm: {
        tenantCode: this.tenantCode,
        assignmentId: this.assignmentId,
        dimensionCode: this.dimensionCode,
        dimensionDataCode: "",
        dimensionDataName: ""
      },
      checkedList: [],
      hintText: "",
      styleObject: {
        display: "none",
        top: "0px",
        left: "0px"
      },
      rightClickNode: null,
      rightClickCount: 0
    };
  },
  created: function () {
    this.initHint();
  },
  methods: {
    init() {
      this.treeData = [];
      this.checkedList = [];
      if (!this.searchForm.assignmentId) {
        this.initHint();
        return;
      }
      this.hintText = this.$t("module.dataPermission.warning.hintWait");
      // 初始化树数据
      dataPermissionAPI.queryTreeDimensionData(this.searchForm).then(data => {
        this.hintText = this.$t("module.dataPermission.noData");
        this.treeData = data || [];
        // 设置选中节点
        this.initCheckedNode(data || []);
        this.$refs["objectTree"].setCheckedKeys(this.checkedList);
      });
    },
    initHint() {
      if (this.controlLevel == CONTROL_LEVEL_ORG) {
        this.hintText = this.$t("module.dataPermission.warning.hintSelectOrg");
      } else if (this.controlLevel == CONTROL_LEVEL_ROLE) {
        this.hintText = this.$t("module.dataPermission.warning.hintSelectRole");
      } else if (this.controlLevel == CONTROL_LEVEL_USER) {
        this.hintText = this.$t("module.dataPermission.warning.hintSelectUser");
      }
    },
    initCheckedNode(children) {
      if (!Array.isArray(children)) return;
      children.forEach(node => {
        // 包含子节点
        if (node.recursive && !node.disabled) {
          // 禁用子节点
          this.disableNode(node.children);
        }
        this.initCheckedNode(node.children);
        // 勾选的节点
        if (node.isAllot == 1) {
          this.checkedList.push(node.dimensionDataId);
        }
      });
      return;
    },
    // 禁用子节点
    disableNode(children) {
      if (!Array.isArray(children)) return;
      children.forEach(node => {
        // 标记为勾选节点
        node.isAllot = 1;
        // 禁用节点
        node.disabled = true;
        // 禁用子节点
        this.disableNode(node.children);
      });
    },
    save() {
      // 保存已分配维度数据
      let checkedNodes = this.$refs["objectTree"].getCheckedNodes();
      let assignedData = [];
      checkedNodes.forEach(item => {
        if (!item.disabled) {
          assignedData.push({
            dimensionDataCode: item.dimensionDataCode,
            dimensionDataId: item.dimensionDataId,
            dimensionDataName: item.dimensionDataName,
            recursive: item.recursive,
            dimensionDataPath: item.dimensionDataPath
          });
        }
      });

      // orgId: this.assignmentId,
      // dimensionRelId: this.dimensionId,
      let param = {
        assignmentId: this.assignmentId,
        dimensionDataList: assignedData
      };

      dataPermissionAPI
        .saveAssignedTreeDimensionData(param)
        .then(response => {
          this.$message.success({
            content: this.$t("module.dimension.warning.updateSuccessfully"),
            duration: 3
          });
        })
        .catch(response => {
          this.$message.error(response.msg);
        });
    },
    onCheckChange(data, checked, indeterminate) {
      // 隐藏右击菜单
      this.styleObject.display = "none";

      // 已标记节点不处理
      if (data.doNotSave) {
        data.doNotSave = false;
        return;
      }

      // 取消勾选一个包括子节点的节点
      if (!checked && data.recursive) {
        // 取消勾选子节点
        this.checkedList = this.$refs["objectTree"].getCheckedNodes();
        this.resetChecked(data.children);
        this.$refs["objectTree"].setCheckedNodes(this.checkedList);
        data.recursive = false;
      }

      this.save();
    },
    // 右击树
    onRightClick(event, data) {
      // 已禁用节点不处理
      if (data.disabled) {
        this.styleObject.display = "none";
        return;
      }

      // 显示右击菜单
      // 鼠标相对于浏览器窗口的坐标 - 父元素相对于浏览器窗口的坐标
      this.styleObject.top = event.clientY - this.$refs["treeRoot"].getBoundingClientRect().top + "px";
      this.styleObject.left = event.clientX - this.$refs["treeRoot"].getBoundingClientRect().left + "px";
      this.styleObject.display = "block";

      // 右击菜单自动消失
      this.rightClickCount++;
      setTimeout(() => {
        if (this.rightClickCount == 1) {
          this.rightClickCount = 0;
          this.styleObject.display = "none";
        } else {
          this.rightClickCount--;
        }
      }, 5000);

      // 记录当前节点，在右击菜单中使用
      this.rightClickNode = data;
    },
    // 选中当前节点
    checkCurrentNode(currentNode) {
      this.checkedList = this.$refs["objectTree"].getCheckedNodes();
      if (currentNode) {
        currentNode.disabled = true;
        currentNode.recursive = false;
        // 触发勾选事件时，子节点不用保存
        currentNode.doNotSave = true;
        this.checkedList.push(currentNode);
      } else {
        // 右击菜单，选中当前节点
        let currentCheckedNode = this.checkedList.find(node => {
          return node.dimensionDataId == this.rightClickNode.dimensionDataId;
        });
        // 如果是选中状态
        if (currentCheckedNode) {
          // 如果是级联选中状态
          if (this.rightClickNode.recursive == true) {
            // 取消级联选中状态
            this.rightClickNode.recursive = false;
            this.resetChecked(this.rightClickNode.children);
            // 如果当前节点是选中状态，不会再次触发选中事件，不会保存
            // 保存变化
            this.save();
          }
        } else {
          // 如果是未选中状态
          this.checkedList.push(this.rightClickNode);
        }
        // 隐藏右击菜单
        this.styleObject.display = "none";
      }
      // 刷新树
      this.$refs["objectTree"].setCheckedNodes(this.checkedList);
    },
    // 选中子节点
    checkChildrenNode(children) {
      if (children) {
        // 非右击菜单
        children.forEach(node => {
          // 选中当前节点
          this.checkCurrentNode(node);
          // 选中子节点
          this.checkChildrenNode(node.children);
        });
      } else {
        // 右击菜单，选中当前节点及子节点
        let checkedNodes = this.$refs["objectTree"].getCheckedNodes();
        let currentCheckedNode = checkedNodes.find(node => {
          return node.dimensionDataId == this.rightClickNode.dimensionDataId;
        });
        // 如果是选中状态
        if (currentCheckedNode) {
          // 如果是单选状态
          if (this.rightClickNode.recursive == false) {
            this.rightClickNode.recursive = true;
            // 选中子节点
            this.checkChildrenNode(this.rightClickNode.children);
            // 如果当前节点是选中状态，不会再次触发选中事件，不会保存
            // 保存变化
            this.save();
          } else {
            // 如果是级联选中状态
            // 隐藏右击菜单
            this.styleObject.display = "none";
            return;
          }
        } else {
          // 选中当前节点及子节点
          this.rightClickNode.recursive = true;
          // 选中当前节点
          this.checkCurrentNode();
          // 选中子节点
          this.checkChildrenNode(this.rightClickNode.children);
        }
      }
    },
    // 取消勾选子节点
    resetChecked(children) {
      if (!Array.isArray(children)) return;
      children.forEach(node => {
        // 触发勾选事件时，子节点不用保存
        node.doNotSave = true;
        // 取消禁用节点
        node.disabled = false;
        // 取消勾选节点
        node.isAllot = 0;
        for (let index = 0; index < this.checkedList.length; index++) {
          const checkedNode = this.checkedList[index];
          if (checkedNode.dimensionDataId == node.dimensionDataId) {
            this.checkedList.splice(index, 1);
            break;
          }
        }
        // 取消勾选子节点
        this.resetChecked(node.children);
      });
    },
    // 左击树
    onNodeClick() {
      // 隐藏右击菜单
      this.styleObject.display = "none";
    }
  },
  watch: {
    assignmentId(newVal, oldVal) {
      this.searchForm.assignmentId = newVal;
      this.init();
    }
  },
  directives: {}
};
</script>
<style lang="less">
.assign-tree-dimension {
  height: 100%;

  .operation-hint {
    margin-left: 18px;
    color: #7f7f7f;
  }
  .tree-menu {
    width: 140px;
    height: 50px;
    position: absolute;
    display: none;
    border-radius: 4px;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    background-color: white;
    z-index: 99;

    .menu-item {
      width: 100%;
      height: 25px;
      margin: 0px auto;
      padding: 3px 0 0 10px;
      cursor: pointer;
    }
    .menu-item:hover {
      color: #ff6f4b;
      background: #fdf0ef;
    }
  }
  .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
    background-color: #f2f6fc !important;
    border-color: #dcdfe6 !important;
  }
  .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after {
    background-color: #f2f6fc;
  }
}
</style>
